use std::str::FromStr;

use crate::http::error::HttpParseError;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum HttpContentType {
    TextPlain,
    TextHtml,
    TextCss,
    ApplicationJavascript,
    ApplicationJson,
    OctetStream,
}

impl HttpContentType {
    pub fn from_extension(ext: &str) -> Self {
        match ext {
            "html" => HttpContentType::TextHtml,
            "css" => HttpContentType::TextCss,
            "js" => HttpContentType::ApplicationJavascript,
            "json" => HttpContentType::ApplicationJson,
            _ => HttpContentType::OctetStream,
        }
    }
}

impl Default for HttpContentType {
    fn default() -> Self {
        Self::TextPlain    
    }
}

impl FromStr for HttpContentType {
    type Err = HttpParseError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.trim() {
            "text/plain" => Ok(Self::TextPlain),
            "text/html" => Ok(Self::TextHtml),
            "text/css" => Ok(Self::TextCss),
            "application/javascript" => Ok(Self::ApplicationJavascript),
            "application/json" => Ok(Self::ApplicationJson),
            "application/octet-stream" => Ok(Self::OctetStream),
            _ => Err(HttpParseError::UnsupportedContentType(s.into())),
        } 
    }
}

impl ToString for HttpContentType {
    fn to_string(&self) -> String {
        match self {
            Self::TextPlain => "text/plain",
            Self::TextHtml => "text/html",
            Self::TextCss => "text/css",
            Self::ApplicationJavascript => "application/javascript",
            Self::ApplicationJson => "application/json",
            Self::OctetStream => "application/octet-stream",
        }
        .to_string()
    }
}